

#ifndef DFROBOT_K10BOX_H
#define DFROBOT_K10BOX_H

#include "Arduino.h"
#include "Wire.h"
#include "unihiker_k10.h"

#define M_PI			(3.14159265358979323846f)

#define IO_Device_addr      0x20                      // IO扩展的设备地址
#define LINE_PATROL_ADDR    0x30                      // 巡线传感器的设备地址
#define QMI8658C_ADDR       0x6B                      // 巡线传感器的设备地址

#define QMI8658_DISABLE_ALL				(0x0)
#define QMI8658_ACC_ENABLE				(0x1)
#define QMI8658_GYR_ENABLE				(0x2)
#define QMI8658_ACCGYR_ENABLE			(QMI8658_ACC_ENABLE | QMI8658_GYR_ENABLE)

#define	QMI8658_ACCRANGE_2G       0x00 << 4
#define	QMI8658_ACCRANGE_4G       0x01 << 4
#define	QMI8658_ACCRANGE_8G       0x02 << 4
#define	QMI8658_ACCRANGE_16G      0x03 << 4

#define QMI8658_ACCODR_8000HZ     0x00
#define QMI8658_ACCODR_4000HZ     0x01
#define QMI8658_ACCODR_2000HZ     0x02
#define QMI8658_ACCODR_1000HZ     0x03
#define QMI8658_ACCODR_500HZ      0x04
#define QMI8658_ACCODR_250HZ      0x05
#define QMI8658_ACCODR_125HZ      0x06
#define QMI8658_ACCODR_62_5HZ     0x07
#define QMI8658_ACCODR_31_25HZ    0x08

#define QMI8658_GRYORANG_16DPS    0x00 << 4
#define QMI8658_GRYORANG_32DPS    0x01 << 4
#define QMI8658_GRYORANG_64DPS    0x02 << 4
#define QMI8658_GRYORANG_128DPS   0x03 << 4
#define QMI8658_GRYORANG_256DPS   0x04 << 4
#define QMI8658_GRYORANG_512DPS   0x05 << 4
#define QMI8658_GRYORANG_1024DPS  0x06 << 4
#define QMI8658_GRYORANG_2048DPS  0x07 << 4

#define QMI8658_GRYOODR_8000HZ     0x00
#define QMI8658_GRYOODR_4000HZ     0x01
#define QMI8658_GRYOODR_2000HZ     0x02
#define QMI8658_GRYOODR_1000HZ     0x03
#define QMI8658_GRYOODR_500HZ      0x04
#define QMI8658_GRYOODR_250HZ      0x05
#define QMI8658_GRYOODR_125HZ      0x06
#define QMI8658_GRYOODR_62_5HZ     0x07
#define QMI8658_GRYOODR_31_25HZ    0x08


#define I2C_READ_IO_VALUE_A 0X00
#define I2C_READ_IO_VALUE_B 0X01
#define I2C_WRITE_IO_VALUE_A 0X02
#define I2C_WRITE_IO_VALUE_B 0X03

#define I2C_CONFIG_IO_MODE_A 0X06
#define I2C_CONFIG_IO_MODE_B 0X07

#define I2C_IR_STATE  0X08
  #define IR_DATA_ENABLE  1
  #define IR_DATA_DISABLE 0
#define I2C_IR_DATA_0 0X09
#define I2C_IR_DATA_1 0X0A
#define I2C_IR_DATA_2 0X0B
#define I2C_IR_DATA_3 0X0C

#define I2C_MIC_DATA0 0X0D
#define I2C_MIC_DATA1 0X0E
#define I2C_VR_DATA0 0X0F
#define I2C_VR_DATA1 0X10


#define I2C_SR04_STATE 0X11
  #define SR04_STATE_FREE     0
  #define SR04_STATE_COLLECT  1
  #define SR04_STATE_COMPLETE 2
#define SR04_COLLECT_TIMEROUT 0xff00
  
#define I2C_SR04_DATA0 0X12
#define I2C_SR04_DATA1 0X13

#define I2C_PWM1_FREQ0 0x14    // 这里是 period
#define I2C_PWM1_FREQ1 0x15   // 这里是 period
#define I2C_PWM1_DUTY0 0x16
#define I2C_PWM1_DUTY1 0x17
#define I2C_PWM1_DUTY2 0x18
#define I2C_PWM1_DUTY3 0x19
#define I2C_PWM1_DUTY4 0x1a
#define I2C_PWM1_DUTY5 0x1b
#define I2C_PWM1_DUTY6 0x1c
#define I2C_PWM1_DUTY7 0x1d

#define I2C_PWM2_FREQ0 0x1e   // 这里是 period
#define I2C_PWM2_FREQ1 0x1f   // 这里是 period
#define I2C_PWM2_DUTY0 0x20
#define I2C_PWM2_DUTY1 0x21
#define I2C_PWM2_DUTY2 0x22
#define I2C_PWM2_DUTY3 0x23
#define I2C_PWM2_DUTY4 0x24
#define I2C_PWM2_DUTY5 0x25

#define I2C_PWM3_FREQ0 0x26
#define I2C_PWM3_FREQ1 0x27
#define I2C_PWM3_DUTY2 0x28
#define I2C_PWM3_DUTY3 0x29



class DFRobot_K10Box
{
public:
  DFRobot_K10Box();
  int16_t begin(void);

  uint32_t rgbToColor(uint8_t r, uint8_t g, uint8_t b);

  //获取声音大小值
  uint16_t getSoundVolume();
  //获取旋钮大小值
  uint16_t getKnobValue();
  //获取红外接收码
  uint32_t getIRValue();
  //获取SR04的距离值
  uint16_t getSR04Value();

  //设置两个电机占空比，A和B的值为0~255
  void setMotor1(uint8_t M1A, uint8_t M1B);
  void setMotor2(uint8_t M2A, uint8_t M2B);
  void setMotor1Run(uint8_t dir, uint8_t speed);
  void setMotor2Run(uint8_t dir, uint8_t speed);

  //设置蜂鸣器的频率，单位为hz，范围为1M/(1~65535)=1M~13(HZ)
  void setBuzzer(uint16_t freq);
  void stopBuzzer();

  //设置RYB灯的亮度，每种都为0~255
  // void setRYGValue(uint8_t R, uint8_t Y, uint8_t G);
  void red_analog(uint8_t R);
  void red_digital(uint8_t state);
  void yellow_analog(uint8_t Y);
  void yellow_digital(uint8_t state);
  void green_analog(uint8_t G);
  void green_digital(uint8_t state);

  //巡线模块
  // void initLinePatrol(void);
  //设置巡线指定探头的阈值
  /**
   * @brief Set the Line Patrol Threshold object
   * 
   * @param num (0~4)
   * @param threshold 
   */
  void setLinePatrolThreshold(uint8_t num, uint8_t threshold);
  //获取巡线指定探头的阈值
  uint8_t getLinePatrolThreshold(uint8_t num);

  //获取所有巡线探头的阈值
  // uint8_t* LinePatrolThresholdAll();
  String getLinePatrolThresholdAll();

  //获取巡线指定探头的原始值
  uint8_t getLinePatrolValue(uint8_t num);

  //获取所有巡线探头的原始值
  // uint8_t* getLinePatrolValueAll();
  String getLinePatrolValueAll();

  //获取所有巡线探头的状态值
  String getLinePatrolStatusAll();

  //获取所有巡线探头的状态值
  // uint8_t getLinePatrolStatusAll();

  //六轴
  void initQMI8658C();
  uint8_t readQMI8658CID();
  void setQMI8658CMode(uint8_t mode);
  void setQMI8658CAccConfig(uint8_t rang, uint8_t odr);
  void setQMI8658CGyroConfig(uint8_t rang, uint8_t odr);

  //获取加速度各轴值
  float getAccelerometerXms2();
  float getAccelerometerYms2();
  float getAccelerometerZms2();
  float getStrengthms2();
  float getAccelerometerXmg();
  float getAccelerometerYmg();
  float getAccelerometerZmg();
  float getStrengthmg();


  //获取陀螺仪各轴值
  float getGyroscopeXrads();
  float getGyroscopeYrads();
  float getGyroscopeZrads();
  float getGyroscopeXdps();
  float getGyroscopeYdps();
  float getGyroscopeZdps();
  int16_t ssvtA;
  int16_t ssvtG;
  int16_t accX;
  int16_t accY;
  int16_t accZ;
  int16_t gyroX;
  int16_t gyroY;
  int16_t gyroZ;
  void getQMI8658xyz();

  private:
  void writeReg(uint8_t reg, void* pBuf, size_t size);
  uint8_t readReg(uint8_t reg, void* pBuf, size_t size);
  void writeReg(uint8_t addr, uint8_t reg, void* pBuf, size_t size);
  uint8_t readReg(uint8_t addr,uint8_t reg, void* pBuf, size_t size);
};

#endif
